package com.haiqiu.common.utils.web;

import com.haiqiu.common.exception.BaseException;
import com.haiqiu.common.result.Constants;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author HaiQiu
 * @date 2021/4/10 22:18
 * @desc redis操作工具类
 **/
@Component
public class RedisUtil {

    private final RedisTemplate<String, Object> redisTemplate;

    public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }


    /**
     * 获取hash类型的数据操作对象
     *
     * @return hash类型的数据操作对象
     */
    public HashOperations<String, String, Object> hashOperations() {
        return redisTemplate.opsForHash();
    }

    /**
     * 获取字符串类型的数据操作对象
     *
     * @return 字符串类型的数据操作对象
     */
    public ValueOperations<String, Object> descriptionOperations() {
        return redisTemplate.opsForValue();
    }

    /**
     * 获取链表类型的数据操作对象
     *
     * @return 链表类型的数据操作对象
     */
    public ListOperations<String, Object> listOperations() {
        return redisTemplate.opsForList();
    }

    /**
     * 获取无序集合的数据类型
     *
     * @return 无序集合的数据
     */
    public SetOperations<String, Object> setOperations() {
        return redisTemplate.opsForSet();
    }

    /**
     * 获取有序集合的数据类型
     *
     * @return 有序集合的数据
     */
    public ZSetOperations<String, Object> zSetOperations() {
        return redisTemplate.opsForZSet();
    }


    /**
     * 指定key的失效时间
     *
     * @param ket
     * @param time
     * @return
     */
    public boolean expire(String ket, Long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(ket, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.getStackTrace();
            return false;
        }
    }


    /**
     * 获取key的过期时间
     *
     * @param key
     * @return
     */
    public Long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }


    /**
     * 判断缓存的key是否存在
     *
     * @param key
     * @return
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.getStackTrace();
            return false;
        }
    }


    /**
     * 根据key删除缓存，支持单个或者批量数组
     *
     * @param key
     */
    public void del(String... key) {
        if (key != null && key.length != 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(Arrays.asList(key));
            }
        }
    }

    /**
     * 根据key删除缓存，支持单个或者批量数组
     *
     * @param keys
     */
    public void del(Set<String> keys) {
        redisTemplate.delete(keys);
    }


    /**
     * 模糊匹配前缀为参数的key
     *
     * @param prefixKey 前缀key
     * @return 模糊匹配key
     */
    public Set<String> getKeys(String prefixKey) {
        return redisTemplate.keys(prefixKey + "*");
    }


    /**
     * 普通键值获取
     *
     * @param key 缓存的key
     * @return 缓存的对象
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }


    /**
     * 缓存数据，不设置时间
     *
     * @param key   key
     * @param description 数据
     * @return 是否成功，true成功，false失败
     */
    public boolean set(String key, Object description) {
        return set(key, description, 0L);
    }


    /**
     * 缓存数据
     * 使用stringRedisTemplate操作
     *
     * @param key   key值
     * @param description 数据
     * @param time  缓存时间
     * @return 是否成功，true成功，false失败
     */
    public boolean set(String key, Object description, Long time) {
        try {
            if (time > 0) {
                descriptionOperations().set(key, description, time, TimeUnit.SECONDS);
            } else {
                descriptionOperations().set(key, description);
            }
            return true;

        } catch (Exception e) {
            e.getStackTrace();
            return false;
        }

    }


    /**
     * 清除账户缓存信息
     * @param username 用户名
     * @return 是否成功
     */
    public void clearRedisInfo(String username){
        try {
            //退出登录，删除缓存token
            del(Constants.REDIS_USER + username);
            //清除缓存的权限数据
            del(Constants.REDIS_USER_AUTH + username);
            //redis缓存用户token
            del(Constants.USER_TOKEN + username);
            //缓存redis用户信息
            del(Constants.REDIS_USER_INFO + username);
            //缓存redis在线用户
            del(Constants.ONLINE_KEY + username);
        }catch (Exception e){
            throw new BaseException(Constants.CLEAR_REDIS);
        }
    }


}
